package cn.itcast.nems.order.service.impl;

import cn.itcast.nems.common.bean.VoucherType;
import cn.itcast.nems.order.dao.dataobject.OrderPaymentFlowDO;
import cn.itcast.nems.order.dao.entity.Order;
import cn.itcast.nems.order.dao.entity.OrderEvent;
import cn.itcast.nems.order.dao.entity.OrderRefundReverse;
import cn.itcast.nems.order.dao.mapper.OrderMapper;
import cn.itcast.nems.order.dao.mapper.OrderRefundLineMapper;
import cn.itcast.nems.order.dao.mapper.OrderRefundMapper;
import cn.itcast.nems.order.dao.mapper.OrderRefundReverseMapper;
import cn.itcast.nems.order.dto.OrderEventTypeEnum;
import cn.itcast.nems.order.dto.OrderRefundReverseSummary;
import cn.itcast.nems.order.service.OrderEventService;
import cn.itcast.nems.order.service.OrderPaymentFlowService;
import cn.itcast.nems.order.service.OrderRefundReverseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author liyong
 * create: 2023-09-14 18:57:14
 **/
@Service
@AllArgsConstructor
public class OrderRefundReverseServiceImpl extends ServiceImpl<OrderRefundReverseMapper, OrderRefundReverse> implements OrderRefundReverseService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final OrderEventService orderEventService;
    private final OrderPaymentFlowService orderPaymentFlowService;
    private final OrderMapper orderMapper;
    private final OrderRefundMapper orderRefundMapper;
    private final OrderRefundLineMapper orderRefundLineMapper;
    private final OrderRefundReverseMapper orderRefundReverseMapper;
    @Override
    public Map<String, OrderRefundReverseSummary> findOrderRefundReverseSummarys(Collection<String> orderRefundIds) {
        Map<String, OrderRefundReverseSummary> result = new HashMap<>();
        final List<Map<String, Object>> rows = this.orderRefundReverseMapper.selectOrderRefundReverses(orderRefundIds);
        if (rows != null && !rows.isEmpty()) {
            Map<String, List<Integer>> refundIdAmounts = new HashMap<>();
            rows.forEach(row -> {
                final String orderRefundId = (String) row.get("order_refund_id");
                final Integer amount = (Integer) row.get("amount");
                refundIdAmounts.computeIfAbsent(orderRefundId, id -> new ArrayList<>()).add(amount);
            });
            refundIdAmounts.forEach((refundId, amounts) -> {
                final int count = amounts.size();
                final Integer sumAmount = amounts.stream().reduce(0, (l, r) -> l + r);
                OrderRefundReverseSummary summary = new OrderRefundReverseSummary(refundId, count, sumAmount);
                result.put(refundId, summary);
            });
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> orderRefundBack(String orderRefundId) {
        return orderRefundReverseMapper.orderRefundBack(orderRefundId);
    }

//    @Override
//    @Transactional
//    public String addOrderRefundReverse(OrderRefundReverseDTO orderRefundReverseDTO) {
//        final String orderRefundId = orderRefundReverseDTO.getOrderRefundId();
//        if (!StringUtils.hasText(orderRefundId)) {
//            throw new BizException(BizError.BAD_REQUEST.getStatus(), BizError.BAD_REQUEST.getCode(), "缺少退费单号");
//        }
//        String orderRefundLineId = orderRefundReverseDTO.getOrderRefundLineId();
//        if (!StringUtils.hasText(orderRefundLineId)) {
//            orderRefundLineId = this.orderRefundLineMapper.selectIdByRefunId(orderRefundId);
//            if (!StringUtils.hasText(orderRefundLineId)) {
//                throw new BizException(BizError.BAD_REQUEST.getStatus(), BizError.BAD_REQUEST.getCode(), "没有找到对应的退费单行");
//            }
//            orderRefundReverseDTO.setOrderRefundLineId(orderRefundLineId);
//        }
//        final OrderRefund orderRefund = this.orderRefundMapper.selectById(orderRefundId);
//        final String orderId = orderRefund.getOrderId();
//
//        final Integer amount = orderRefundReverseDTO.getAmount().multiply(BigDecimal.valueOf(100)).intValue();
//        final Integer actualRefundAmount = orderRefund.getAmount();
//        if (amount > 0 && amount > actualRefundAmount) {
//            throw new BizException(BizError.BAD_REQUEST.getStatus(), BizError.BAD_REQUEST.getCode(), "回冲金额不能大于已退金额");
//        }
//
//        final Order order = this.orderMapper.selectById(orderId);
//        final Integer paidAmount = order.getPaidAmount();
//        final Integer orderRefundAmount = order.getRefundAmount();
//        if (amount < 0 && -amount > (paidAmount - orderRefundAmount)) {
//            throw new BizException(BizError.BAD_REQUEST.getStatus(), BizError.BAD_REQUEST.getCode(), "退费的金额不能大于已支付金额");
//        }
//        OrderRefundReverse reverse = new OrderRefundReverse();
//        BeanUtils.copyProperties(orderRefundReverseDTO, reverse);
//        reverse.setAmount(amount);
//        logger.info("create OrderRefundReverse");
//        this.orderRefundReverseMapper.insert(reverse);
//        logger.info("create OrderPaymentFlow");
//        this.addPaymentFlow(order, reverse);
//        logger.info("update OrderRefundAmount");
//        this.orderRefundMapper.updateOrderRefundAmount(orderRefund.getId(), actualRefundAmount - amount);
//        logger.info("update Order RefundAmount");
//        this.updateOrder(order, reverse);
//        logger.info("Reverse finish");
//        return reverse.getId();
//    }

    private void updateOrder(Order order, OrderRefundReverse reverse) {
        final Order updateOrder = new Order();
        updateOrder.setId(order.getId());
        updateOrder.setRefundAmount(order.getRefundAmount() - reverse.getAmount());
        this.orderMapper.updateById(updateOrder);

        OrderEvent eventEntity = new OrderEvent();
        eventEntity.setOrderId(order.getId());
        eventEntity.setType(OrderEventTypeEnum.REFUNDED_REVERSE.getName());
        eventEntity.setDescription("订单退费冲回");
        orderEventService.save(eventEntity);
    }

    private void addPaymentFlow(Order order, OrderRefundReverse reverse) {
        OrderPaymentFlowDO flow = new OrderPaymentFlowDO();
        flow.setOrderId(order.getId());
        flow.setAmount(String.valueOf(reverse.getAmount()));
        flow.setJournalType(VoucherType.REFUND_AMENDMENT.toString());
        flow.setJournalNo(reverse.getId());
        flow.setCharge(String.valueOf(0));
        flow.setChargeRate(BigDecimal.ZERO);
        flow.setBizDate(LocalDateTime.now());
        flow.setPaymentMethodCode("");
        flow.setPaymentMethodName("");
        flow.setPaymentAccountCode("");
        flow.setPaymentAccountName("");
        flow.setRemark(reverse.getRemark());
        this.orderPaymentFlowService.addOrderPaymentFlow(flow);
    }
}
